package com.master.echoserver;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

//Selector轮询线程类
public class SelectorLoop implements Runnable {
    private Selector selector;
     private SelectorLoopType type;
    public static boolean isConnectionReader=false;
    public SelectorLoop(SelectorLoopType type ) throws IOException {
    	this.selector = Selector.open();
        this.type=type;
    }   
    public Selector getSelector() {
        return this.selector;
    }
public void run() {
    	 System.out.println("启动一个监听服务 Thread"+Thread.currentThread().getId());
        while(true) {
            try {
                // 阻塞,只有当至少一个注册的事件发生的时候才会继续.
           int num = this.selector.select();
            if(num>0) {    
                Set<SelectionKey> selectKeys = this.selector.selectedKeys();
                Iterator<SelectionKey> it = selectKeys.iterator();
                while (it.hasNext()) {
                    SelectionKey key = it.next();
                    it.remove();
                    // 处理事件. 可以用多线程来处理.
                    this.dispatch(key);
                }
            }else if(this.type.equals(SelectorLoopType.READER)){
        		List<SocketChannel> tastList =EchoServer.taskQueen;
        		synchronized (tastList) {
                    while(tastList.size() > 0){
                    	SocketChannel sc =  tastList.remove(0);
                        //注册写事件
                    	sc.register(EchoServer.connectionReader.getSelector(), SelectionKey.OP_READ);
                    }
         		
                    }
        }
             } catch (IOException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
           
    }
 public void dispatch(SelectionKey key) throws IOException, InterruptedException {
        if (key.isAcceptable()) {
            System.out.println("监听线程"+Thread.currentThread().getId()+" 处理connection accept事件");
             // 这是一个connection accept事件, 并且这个事件是注册在serversocketchannel上的.
            ServerSocketChannel ssc = (ServerSocketChannel) key.channel();
            // 接受一个连接.
            SocketChannel sc = ssc.accept();
             
            // 对新的连接的channel注册read事件. 使用readBell闹钟.
            sc.configureBlocking(false);
            
            EchoServer.addTaskQueen(sc);  
            System.out.println("监听线程"+Thread.currentThread().getId()+" 注册——op_read事件");
             synchronized (SelectorLoop.class) {
            	if (!SelectorLoop.this.isConnectionReader) {
            		SelectorLoop.this.isConnectionReader = true;
            	   new Thread(EchoServer.connectionReader).start();
 			}}
            }
        else if (key.isReadable()) {
            // 这是一个read事件,并且这个事件是注册在socketchannel上的.
            System.out.println("监听线程"+Thread.currentThread().getId()+" 处理——op_read事件");
            key.cancel();
            RequestProcessor.ProcessorRequest(key);
        } 
        
    }

}    